import datetime
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
from web import models
from django.conf import settings


class Tracer(object):
    """封装一个类，存储用户信息和价格策略,目的是将多个属性封装到request.tracer"""

    def __init__(self):
        self.user = None
        self.price_policy = None
        self.project = None


class UserAuthMiddleware(MiddlewareMixin):
    """自定义中间件对请求进行鉴权"""

    def process_request(self, request):
        # 实例化Tracer赋值给request.tracer
        request.tracer = Tracer()
        """如果用户已经登录，则在中间件中对request进行赋值"""
        userid = request.session.get('info', 0)  # 因为id是整形，所以取不到值要赋0，不能赋空
        user_obj = models.Account.objects.filter(id=userid).first()
        request.tracer.user = user_obj

        if request.path_info in settings.MIDDLEWARE_WHITE_LIST:
            return

        if not userid:
            return redirect('/login/')

        # 获取用户的交易情况信息
        # 获取状态为已支付，且按照id降序获取第一条查到的交易信息
        obj = models.Transaction.objects.filter(user=user_obj, status=1).order_by('-id').first()
        # 当不是免费版且已经过期的情况下，按照免费版进行限额
        if obj.end_datetime and obj.end_datetime < datetime.datetime.now():
            obj = models.Transaction.objects.filter(user=user_obj, status=1, price_policy__category=0).first()
        # 将价格策略存储到request中
        request.tracer.price_policy = obj.price_policy


    """
    判断用户是否进入项目：
    1.url是否以/manage/开头
    2.project_id是否为当前用户参与或创建的项目id
    如果进入项目，则向request.tracer.project存入项目对象
    """
    # process_view 方法是在process_request 执行完毕后，获取url之后，进入视图函数之前会调用的方法
    def process_view(self, request, view, args, kwargs):
        # url是否以/manage/开头,则向下判断，如果不是，则中间件return None放行
        if not request.path_info.startswith('/manage/'):
            return
        # 通过kwargs获取目标视图函数的关键字参数 project_id
        project_id = kwargs.get('project_id')
        # 查询此id是否为我创建的项目
        project_object = models.Project.objects.filter(id=project_id, creator=request.tracer.user).first()
        if project_object:
            request.tracer.project = project_object
            return
        # 查询此id是否为我参与的项目
        projectUser_object = models.ProjectUser.objects.filter(project=project_id, user=request.tracer.user).first()
        if projectUser_object:
            request.tracer.project = projectUser_object.project  # projectUser_object 对象需要加上.project 才是关联的project项目对象
            return
        return redirect('/project/list/')

    def process_response(self, request, response):
        return response
